
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>事件驱动模型 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>事件驱动模型 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">Netty的事件驱动模型带来了哪些核心优势？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Netty的事件驱动模型使得应用程序能够以非阻塞、异步的方式处理网络事件，从而极大地提高吞t吐量和并发性能。它能够高效处理大量并发连接，并实现良好的资源隔离。</div>
          </div>
          <div class="card-source">来源: Netty事件驱动模型源码分析</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">Netty事件驱动模型中的两个核心概念是什么，它们各自的作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">两个核心概念是`EventLoop`和`ChannelHandler`。`EventLoop`负责处理事件循环，是事件驱动模型的核心组件；`ChannelHandler`则负责处理具体的I/O事件。</div>
          </div>
          <div class="card-source">来源: 1. 事件驱动模型概述</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在Netty中，`EventLoop`是如何处理I/O事件的？请描述其基本工作流程。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">每个`EventLoop`在一个独立的线程中运行。它的工作流程是：1. 启动后进入无限循环；2. 监听并轮询各个Channel的I/O事件；3. 当某个Channel准备好I/O操作时，将其加入任务队列，并传递给相应的`ChannelHandler`进行处理。</div>
          </div>
          <div class="card-source">来源: 2. 事件循环（Event Loop）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">`Channel`、`ChannelPipeline`和`ChannelHandler`三者之间是如何协作的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">每个`Channel`都有一个关联的`ChannelPipeline`，`ChannelPipeline`是一个包含了多个`ChannelHandler`的链表。当一个I/O事件发生时，该事件会在`ChannelPipeline`中按照顺序被传递，由链中的各个`ChannelHandler`依次进行处理。</div>
          </div>
          <div class="card-source">来源: 3. Channel 与 ChannelHandler 的协作</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">架构</div>
          <div class="card-question">什么是`EventLoopGroup`？它在Netty中扮演什么角色？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">架构</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`EventLoopGroup`是由多个`EventLoop`组成的集合。它的主要职责是为新接入的`Channel`分配和管理`EventLoop`，通常采用轮询等方式进行分配，以确保每个连接都有独立的事件处理线程，从而提高系统的并发能力。</div>
          </div>
          <div class="card-source">来源: 4. EventLoopGroup 的管理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">Netty的事件驱动模型与异步I/O（Non-blocking I/O）有什么关系？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Netty的事件驱动模型是基于异步I/O操作实现的。所有的I/O操作（如连接、读、写）都不会阻塞当前线程，而是通过事件驱动的方式异步地触发，并将事件通知给相关的`ChannelHandler`进行处理，从而在单线程中处理多个连接，提高系统吞吐量。</div>
          </div>
          <div class="card-source">来源: 5. 事件驱动模型与异步 I/O</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">Netty是如何结合事件驱动模型进行高效内存管理的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Netty提供了高效的内存池机制`ByteBufAllocator`。当需要分配缓冲区来处理网络数据时，它会通过`ByteBufAllocator`来分配内存，从而避免了内存频繁分配和回收带来的开销，提升了性能。</div>
          </div>
          <div class="card-source">来源: 6. 事件驱动与内存管理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">`ByteBufAllocator`提供了哪两种类型的内存分配方式？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`ByteBufAllocator`提供了`directBuffer()`和`heapBuffer()`两种方法，分别用于分配直接内存（堆外内存）和堆内存。</div>
          </div>
          <div class="card-source">来源: 6. 事件驱动与内存管理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">当`EventLoop`检测到`Channel`上有可读事件时，它是如何触发事件在`ChannelPipeline`中传播的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">当`EventLoop`检测到某个`Channel`上有数据可读事件时，它会调用`fireChannelRead()`方法将事件传递到`ChannelPipeline`的头部，之后事件会沿着`ChannelPipeline`中的`ChannelHandler`链顺序传播下去进行处理。</div>
          </div>
          <div class="card-source">来源: 3. Channel 与 ChannelHandler 的协作</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
